﻿module main;

import std.stdio;

enum SubscriberEvents {
	PushButtonEventClicked
};

extern (C++) interface EventHandler {
public:
	bool eventCallback(void *args);
};

alias bool delegate(void *) eventdelegate;

class GuiEventDelegate : EventHandler {
	package this(eventdelegate dg_) { dg = dg_; }
	extern (C++) bool eventCallback(void *args) {
		return dg(args);
	}
private:
	eventdelegate dg;
}


bool addEventSubscriber(string name, SubscriberEvents event, eventdelegate handler) {

	if(checkEventSubscriber(name, event)) {
		debug writeln("An event subscriber already present for widget ", name, ", ", event);
		return false;
	}
	THandlers handlers;
	if(name in subscribers) handlers = subscribers[name];
	auto h = new GuiEventDelegate(handler);
	handlers[event] = h;
	subscribers[name] = handlers;

	return true;
}

alias GuiEventDelegate[SubscriberEvents] THandlers;
THandlers[string] subscribers;

bool checkEventSubscriber(string name, SubscriberEvents event) {
	if(name in subscribers) {
		auto handlers = subscribers[name];
		if(event in handlers) return true;
	} else 
		writeln(name," not in subscribers");
	return false;
}

class handlertest {
	bool callback(void *) {
		writeln("called");
		return true;
	}
}

int main(string[] argv)
{
	handlertest ht = new handlertest();

	immutable string name = "handlertest";

	writeln(checkEventSubscriber(name,SubscriberEvents.PushButtonEventClicked));

	writeln(addEventSubscriber(name,SubscriberEvents.PushButtonEventClicked,
							   &ht.callback));

	writeln(subscribers[name][SubscriberEvents.PushButtonEventClicked].eventCallback(null));

	writeln(checkEventSubscriber(name,SubscriberEvents.PushButtonEventClicked));

	writeln(addEventSubscriber(name,SubscriberEvents.PushButtonEventClicked,
							   &ht.callback));
	return 0;
}
